package com.qiji.video.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qiji.video.bean.BrowsingHistory;
import com.qiji.video.bean.Collection;
import com.qiji.video.bean.Comments;
import com.qiji.video.bean.Users;
import com.qiji.video.bean.dto.UserDto;
import com.qiji.video.exception.ServiceException;
import com.qiji.video.mapper.UsersMapper;
import com.qiji.video.mapper.extend.UserExtendMapper;
import com.qiji.video.service.IUserService;
import com.qiji.video.service.async.AsyncService;
import com.qiji.video.util.Md5Util;
import com.qiji.video.util.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private UserExtendMapper userExtendMapper;
    @Autowired
    private JavaMailSenderImpl javaMailSender;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private AsyncService asyncService;
    // 邮箱 : 验证码+发送验证码时间
    ConcurrentHashMap<String,String> map=new ConcurrentHashMap();


    @Autowired
    @Qualifier("RedisTemplate")
    private RedisTemplate redisTemplate;

    @Override
    public Users userLogin(String username,String password) throws ServiceException {
        Users ur = (Users) redisTemplate.opsForHash().get("Login:User:"+username+"", username);
        // 缓存有数据
        if(ur!=null && ur.getPassword().equals(Md5Util.getMd5Key(password))){
            // 异步任务 更新缓存
            asyncService.updateLoginTime(ur,username);
            return ur;
        }
        Users user=null;
        if (username.indexOf("@")>=0){
            user=userExtendMapper.getUserByEmail(username);
        }else{
            user = userExtendMapper.getUserByPhone(username);
        }
//        //用户为空
//        if (user==null){
//            throw new ServiceException(ResultCode.USER_NULL);
//        }else{
//            //密码错误
//            if(!Md5Util.getMd5Key(password).equals(user.getPassword())){
//                throw new ServiceException(ResultCode.PASSWORD_ERROR);
//            }
//        }
        // 异步任务 更新缓存
        asyncService.updateLoginTime(user,username);

        return user;
    }
    @Override
    public Users selectUser(Integer id) {
        Users user = usersMapper.selectByPrimaryKey(id);
        System.out.println(user);
        redisTemplate.opsForHash().put("Login:User:"+user.getPhone()+"",user.getPhone(),user);
        redisTemplate.opsForHash().put("Login:User:"+user.getEmail()+"",user.getEmail(),user);
        redisTemplate.expire("Login:User:"+user.getPhone()+"",2, TimeUnit.DAYS);
        redisTemplate.expire("Login:User:"+user.getEmail()+"",2, TimeUnit.DAYS);
        return user;
    }

    @Override
    public int updatePwdByPhone(Users users) throws ServiceException {
        if (userExtendMapper.getUserByPhone(users.getPhone())==null){
            throw new ServiceException(ResultCode.USER_NULL);
        }else{
            return userExtendMapper.updateByPhone(users);
        }
    }

    @Override
    public int updatePwdByEmail(String email, String password,String verCode) throws ServiceException {
        // 邮箱验证码
        String mailVerCode = map.get(email).substring(0,8);
        Long time = Long.valueOf(map.get(email).substring(9,map.get(email).length()));
        // 验证码有效期一分钟
        if (System.currentTimeMillis()-time>60000){
            throw new ServiceException(ResultCode.VERIFICATIONCODE_EXPIRE);
        }else {
            if (!verCode.equals(mailVerCode)){
                throw new ServiceException(ResultCode.VERIFICATIONCODE_ERROR);
            }else{
                if (userExtendMapper.getUserByEmail(email)!=null){
                    return userExtendMapper.updateByEmail(email,password);
                }else{
                    throw new ServiceException(ResultCode.USER_NULL);
                }
            }
        }
//        return 0;
    }

    @Override
    public PageInfo<BrowsingHistory> selectBhByUid(Integer uid,Integer page,Integer size) {
        // 当前页 页面大小
        PageHelper.startPage(page,size);
        PageInfo<BrowsingHistory> info=new PageInfo<BrowsingHistory>(userExtendMapper.selectBhByUid(uid));
        return info;
    }

    @Override
    public PageInfo<Comments> selectByVid(Integer vid,Integer page,Integer size) {
        PageHelper.startPage(page,size);
        PageInfo<Comments> info=new PageInfo<Comments>(userExtendMapper.selectByVid(vid));
        return info;
    }

    @Override
    public PageInfo<Collection> selectCollectByUid(Integer uid,Integer page,Integer size) {
        PageHelper.startPage(page,size);
        PageInfo<Collection> info=new PageInfo<Collection>(userExtendMapper.selectCollectByUid(uid));
        return info;
    }

    /*
        缓存更新策略：
            先更新数据库，更新成功后删除缓存
     */
    @Override
    public int updateInfoSelective(UserDto users) throws ServiceException {
        Users user = usersMapper.selectByPrimaryKey(users.getId());
//        if (redisTemplate.opsForHash().get(user.getEmail(),user.getEmail())!=null){
//            redisTemplate.delete(user.getEmail());
//        }else if (redisTemplate.opsForHash().get(user.getPhone(),user.getPhone())!=null){
//            System.out.println("redis");
//            redisTemplate.delete(user.getPhone());
//        }
        // 更新数据库
        int update = userExtendMapper.updateByPrimaryKey(users);
        if (update>=0){
            // 删除缓存
            if (redisTemplate.opsForHash().get("Login:User:"+user.getEmail()+"",user.getEmail())!=null){
                redisTemplate.delete("Login:User:"+user.getEmail()+"");
            }else if (redisTemplate.opsForHash().get("Login:User:"+user.getPhone()+"",user.getPhone())!=null){
                redisTemplate.delete("Login:User:"+user.getPhone()+"");
            }
        }else {
            throw new ServiceException(ResultCode.UPDATE_ERROR);
        }
        return update;
    }

    @Override
    public boolean sendEmail(String email) throws MessagingException {
        // 使用线程池 异步邮件发送
        threadPoolExecutor.execute(()->{
            MimeMessage message=javaMailSender.createMimeMessage();
            MimeMessageHelper helper= null;
            try {
                helper = new MimeMessageHelper(message,true);
                String verCode = UUID.randomUUID().toString().substring(0, 8);
                helper.setSubject("登录验证");
                helper.setText("<div style='text-align:center;'><h1>您的验证码如下:</h1><br/>" +
                        "<h2>'"+verCode+"'</h2>" +
                        "</div>",true);
                helper.setFrom("2128521493@qq.com");
                helper.setTo(email);
                javaMailSender.send(message);

                map.put(email,verCode+":"+System.currentTimeMillis());

            } catch (MessagingException e) {
                e.printStackTrace();
            }
        });
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }
}
